module.exports = function (lab) {
    return {
        "saveOU": function (session, form) {

            if (!session.currentOU) {
                throw @lab.errors.not_login;
            }
            if (!form) {
                throw @lab.errors.invalid_parameters;
            }

            if (form.id) {
                delete form.id;
            }

            return lab.find("backend_operation_units", session.currentOU.id).then(function (existing_ou) {
                lab.backend.ou.@saveOU(@.merge.simple(existing_ou, form)).pipe(this);
            })
        },
        "@saveOU": function ({
            id,
            name,
            type,
            services
        }) {

            if (!name) {
                throw @lab.errors.empty_name;
            }

            return lab.snapshot(function (snapshot) {

                return @.async(function () {

                    if (id) {

                        snapshot.find("backend_operation_units", id).then(function (existing_ou) {
                            if (existing_ou) {
                                this.next(existing_ou);
                            } else {
                                throw @lab.errors.object_not_found;
                            }
                        }).pipe(this);

                    } else {
                        this.next();
                    }

                }).then(function (existing_ou) {

                    if (existing_ou) {
                        snapshot.update("backend_operation_units", existing_ou, {
                            name,
                            type
                        }).pipe(this);
                    } else {

                        snapshot.create("backend_operation_units", {
                            name       : name,
                            type       : type,
                            is_removed : false
                        }).pipe(this);
                    }

                }).then(function (ou) {

                    if (services) {

                        @.async.all(@.keys(services), function (name) {

                            snapshot.sqlite.find("backend_service_settings", {
                                name: name,
                                ouid: ou.id
                            }).then(function (result) {

                                if (result.records.length) {

                                    @.async.all(result.records, function (record) {

                                        if (services[name]) {
                                            record.value = (@.is(services[name], String) ? {
                                                rootURL: services[name]
                                            } : services[name]);
                                        } else {
                                            delete record.settings;
                                        }

                                        record.status = 0;

                                        @.async(function () {

                                            snapshot.update("backend_service_settings", record).pipe(this);

                                        }).then(function () {

                                            snapshot.sqlite.find("backend_service_keyrings", {
                                                service_id: record.id
                                            }).pipe(this);

                                        }).then(function (keyring_result) {

                                            @.async.all(keyring_result.records, function (keyring) {

                                                keyring.expire_date = 0;
                                                snapshot.update("backend_service_keyrings", keyring).pipe(this);

                                            }).pipe(this);
                                        })

                                    }).pipe(this);

                                } else if (services[name]) {

                                    snapshot.create("backend_service_settings", {
                                        name: name,
                                        ouid: ou.id,
                                        status: 0,
                                        value: (@.is(services[name], String) ? {
                                            rootURL: services[name]
                                        } : services[name])
                                    }).pipe(this);

                                } else {
                                    this.next();
                                }

                            }).pipe(this);

                        }).resolve(ou).pipe(this);

                    } else {
                        this.next(ou);
                    }

                });

            })



        }
    }
}